package org.seedltd.upms.service.impl.sys;

import java.io.Serializable;
import java.util.List;
import java.util.Optional;

import org.seedltd.base.exception.BusinessException;
import org.seedltd.core.base.BasePage;
import org.seedltd.core.utils.SqlUtils;
import org.seedltd.core.utils.StringUtils;
import org.seedltd.upms.mapper.sys.SysDictMapper;
import org.seedltd.upms.model.sys.entity.SysDict;
import org.seedltd.upms.model.sys.form.SysDictForm;
import org.seedltd.upms.model.sys.form.SysDictSearchForm;
import org.seedltd.upms.model.sys.vo.DictEnumVO;
import org.seedltd.upms.model.sys.vo.SysDictVO;
import org.seedltd.upms.service.sys.SysDictService;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

/**
 * 字典管理带缓存的业务实现
 * 
 * @author laizuan
 * @since 2021/07/24
 * @version 1.0
 */
@Service
@CacheConfig(cacheNames = "SysDict#30d")
public class SysDictServiceImpl implements SysDictService {
    private final SysDictMapper sysDictMapper;
    private final SysDictService sysDictService;

    public SysDictServiceImpl(SysDictMapper sysDictMapper, @Lazy SysDictService sysDictService) {
        this.sysDictMapper = sysDictMapper;
        this.sysDictService = sysDictService;
    }

    @Override
    public SysDict findById(Serializable id) {
        return sysDictMapper.selectById(id);
    }

    @Override
    @CacheEvict(key = "#form.dictType")
    public boolean update(SysDictForm form) {
        if (sysDictMapper.checkExistsDictType(form.getDictType()) == null) {
            throw new BusinessException(String.format("字典类型【%s】不存在", form.getDictType()));
        }
        return SqlUtils.u(sysDictMapper).updateById(form, form.getDictId());
    }

    @Override
    @CacheEvict(key = "#type")
    public boolean delete(String type, Long id) {
        if (id == null && StringUtils.isNotBlank(type)) {
            return SqlUtils.u(sysDictMapper).eq(SysDict::getDictType, type).delete();
        }
        return SqlUtils.retBool(sysDictMapper.deleteById(id));
    }

    @Override
    @CacheEvict(key = "#type")
    public void clearCache(String type) {
        // nothing, only delete cache
    }

    @Override
    @CacheEvict(key = "#form.dictType")
    public SysDict add(SysDictForm form) {
        if (sysDictMapper.checkExistsDictType(form.getDictType()) == null) {
            throw new BusinessException(String.format("字典类型【%s】不存在", form.getDictType()));
        }
        return SqlUtils.u(sysDictMapper).save(form, new SysDict());
    }

    @Override
    public BasePage<SysDictVO> page(SysDictSearchForm searchForm) {
        return SqlUtils.q(sysDictMapper, searchForm).selectPage(searchForm.getStart(), searchForm.getSize(),
            SysDictVO.class);
    }

    @Override
    @Cacheable(key = "#type", unless = "#result == null")
    public List<DictEnumVO> listSimpleByType(String type) {
        return sysDictMapper.listSimpleByType(type);
    }

    @Override
    public DictEnumVO findByTypeAndValue(String type, String value1) {
        if (StringUtils.isBlank(value1) || StringUtils.isBlank(type)) {
            return null;
        }
        List<DictEnumVO> sysDicts = sysDictService.listSimpleByType(type);
        if (CollectionUtils.isEmpty(sysDicts)) {
            return null;
        }
        Optional<DictEnumVO> first = sysDicts.stream().filter(item -> item.getValue().equals(value1)).findFirst();
        return first.orElse(null);
    }
}